package cn.ljy.authority.config.security.user;

import cn.ljy.common.model.result.ResponseData;
import cn.ljy.common.model.result.ResultCode;
import cn.ljy.common.utils.ResponseUtil;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 处理后台匿名用户访问无权限资源时的异常(注意这些异常只能在这里捕获，@ControllerAdvice无法捕获)
 * 在验证登陆状态失败时会发生
 * AuthenticationEntryPoint：该异常类实现了很多子类，概括来说都是身份校验问题。
 * AuthenticationException子实现
 * UsernameNotFoundException：用户名未找到。
 * BadCredentialsException：认证错误。可以用于密码错误、验证码错误等。
 * RememberMeAuthenticationException：记住我 认证错误。 在登录中常常有 记住我 选项，因为这个地方导致的错误。
 * AccountStatusException：用户账户状态异常。例如被封号之类的。
 * NonceExpiredException：Nonce过期异常。
 * AuthenticationCredentialsNotFoundException：SecurityContext中不存在Authentication异常。
 * AuthenticationServiceException：认证服务异常。可能是后端数据库之类的出现问题等等情况。
 * ProviderNotFoundException：Provider找不到异常。由ProviderManager抛出。
 * SessionAuthenticationException：会话认证异常。通常是因为同一个用户打开了多个会话。
 * InsufficientAuthenticationException：认证信息不足异常？可能是由于 记住我 选项引发的。
 */
@Component
public class UserAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        String message=null;
        if(authException instanceof AuthenticationCredentialsNotFoundException){
            message="未能找到用户名";
        }else if(authException instanceof LockedException){
            message="账户已被锁定，请联系管理员";
        }else if(authException instanceof DisabledException){
            message="账户已被禁用，请联系管理员";
        }else if(authException instanceof InsufficientAuthenticationException){//认证信息不足异常，例如登陆信息已经失效（session不存在该值）
            message="请先登陆";
        }
        ResponseUtil.responseJson(response, ResponseData.error(ResultCode.UNAUTHORIZED.getCode(),message));
    }
}
